package org.railage.client.gui.tabs;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTable;

import org.apache.log4j.Logger;
import org.railage.client.Client;
import org.railage.client.gui.dialogs.TicketBuyDialog;
import org.railage.client.gui.main.GUI;
import org.railage.common.dto.ScheduleRecordDTO;

import javax.swing.JScrollPane;
import javax.swing.table.DefaultTableModel;
import javax.swing.DefaultComboBoxModel;

import java.awt.Dialog.ModalityType;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class ScheduleTab extends AbstractTab {

	private static final long serialVersionUID = -3404641839514507539L;

	private static final Logger log = Logger.getLogger(ScheduleTab.class);

	private static final String SELECT_STATION = "-- Select station --";

	private JComboBox<String> comboBoxStations;
	private JTable timeTable;

	private SimpleDateFormat dateTimeFormatter = new SimpleDateFormat(
			GUI.DATE_FORMAT + " " + GUI.TIME_FORMAT);

	private String[] stations = null;
	private String[] columnNames = new String[] { "Arrival", "Departure",
			"Trip ID", "Route" };

	public ScheduleTab() {
		setLayout(null);

		JLabel lblStation = new JLabel("Station");
		lblStation.setBounds(41, 22, 46, 14);
		add(lblStation);

		comboBoxStations = new JComboBox<String>();
		comboBoxStations.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				fillTimetable((String) comboBoxStations.getSelectedItem());
			}
		});
		comboBoxStations.setBounds(159, 19, 200, 20);
		add(comboBoxStations);

		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setBounds(0, 62, 720, 328);
		add(scrollPane);

		timeTable = new JTable();
		timeTable.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				if (e.getClickCount() == 2) {
					int row = timeTable.rowAtPoint(e.getPoint());
					int tripID = (Integer) timeTable.getValueAt(row, 2);
					TicketBuyDialog ticketDialog = new TicketBuyDialog(tripID);
					ticketDialog
							.setModalityType(ModalityType.APPLICATION_MODAL);
					ticketDialog.init();
				}
			}
		});
		scrollPane.setViewportView(timeTable);
	}

	public void init() {
		fillCombobox();
		timeTable
				.setModel(new DefaultTableModel(new Object[][] {}, columnNames));
	}

	private void fillCombobox() {
		try {
			stations = (String[]) Client.getInstance().callMethod(
					"getStationNames", null);
			String[] items = new String[stations.length + 1];
			items[0] = SELECT_STATION;
			System.arraycopy(stations, 0, items, 1, stations.length);

			comboBoxStations.setModel(new DefaultComboBoxModel<String>(items));
		} catch (IOException e) {
			log.error(GUI.DISCON_UNEXP_LOG_MSG, e);
			JOptionPane.showMessageDialog(this, GUI.DISCON_UNEXP_GUI_MSG);
		}
	}

	private void fillTimetable(String station) {
		Object[][] data = new Object[][] {};
		if (!station.equals(SELECT_STATION)) {
			ScheduleRecordDTO[] schedule = null;
			try {
				schedule = (ScheduleRecordDTO[]) Client.getInstance()
						.callMethod("getSchedule", station);
				data = new Object[schedule.length][];
				int i = 0;
				for (ScheduleRecordDTO record : schedule) {
					Date arrival = new Date(record.getArrival().getTime());
					Date departure = new Date(record.getDeparture().getTime());
					data[i] = new Object[] { dateTimeFormatter.format(arrival),
							dateTimeFormatter.format(departure),
							record.getTrip(), record.getRoute() };
					i++;
				}
			} catch (IOException e) {
				log.error(GUI.DISCON_UNEXP_LOG_MSG, e);
				JOptionPane.showMessageDialog(this, GUI.DISCON_UNEXP_GUI_MSG);
			}
		}
		timeTable.setModel(new DefaultTableModel(data, columnNames) {
			private static final long serialVersionUID = 7581819156666647878L;

			@Override
			public boolean isCellEditable(int row, int column) {
				return false;
			}
		});
	}
}
